iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0

今天就來實作看看 CRUD 吧! 假設客戶是一家書店,最近想要推出折價卷功能進行促銷…

  1. 新建一個 rails app
$ rails new coupon
$ cd coupon
$ vode . # 快捷開始 VS CODE
  1. books_coupons 的 route 使用 resources
Rails.application.routes.draw do

  resources :books_coupons, only: [:new, :create, :index]
end
  1. 建立一個折價券模型
$ rails g model BooksCoupon code:string discount:decimal expires_at:datetime max_uses:integer used_count:integer
  1. db/migrate 目錄中找到新建立的 Migration, 增加以下:
class CreateBooksCoupons < ActiveRecord::Migration[7.0]
  def change
    create_table :books_coupons do |t|
      t.string :code
      t.decimal :discount, precision: 8, scale: 2
      t.datetime :expires_at
      t.integer :max_uses
      t.integer :used_count, default: 0

      t.timestamps
    end
  end
end

然後執行遷移:

$ rails db:migrate
  1. 在 BooksCoupon 模型中加上驗證和方法:
class BooksCoupon < ApplicationRecord
  validates :code, presence: true, uniqueness: true
  validates :discount, presence: true, numericality: { greater_than: 0 }
  validates :expires_at, presence: true

  def available?
    !expired? && (max_uses.nil? || used_count < max_uses)
  end

  def expired?
    expires_at.present? && expires_at < DateTime.now
  end

  def apply_discount(amount)
    [amount - discount, 0].max
  end
end
  1. 建立一個 controller 來管理折價券
$ rails g controller BooksCoupons 

在 app/controllers/books_coupons_controller.rb 中:

class BooksCouponsController < ApplicationController
  def new
    @books_coupon = BooksCoupon.new
  end

  def create
    @books_coupon = BooksCoupon.new(books_coupon_params)
    if @books_coupon.save
      redirect_to books_coupons_path, notice: 'Coupon created successfully.'
    else
      render :new
    end
  end

  def index
    @books_coupons = BooksCoupon.all
  end

  private

  def books_coupon_params
    params.require(:coupon).permit(:code, :discount, :expires_at, :max_uses)
  end
end

  1. 接著建立一個折價券的 view

在 app/views/books_coupons 目錄下建立 new.html.erb 和 index.html.erb

# app/views/books_coupons/new.html.erb

<%= form_with(model: @books_coupon, url: books_coupons_path) do |form| %>
  <div class="field">
    <%= form.label :code %>
    <%= form.text_field :code %>
  </div>

  <div class="field">
    <%= form.label :discount %>
    <%= form.number_field :discount %>
  </div>

  <div class="field">
    <%= form.label :expires_at %>
    <%= form.datetime_field :expires_at %>
  </div>

  <div class="field">
    <%= form.label :max_uses %>
    <%= form.number_field :max_uses %>
  </div>

  <div class="actions">
    <%= form.submit 'Create Coupon' %>
  </div>
<% end %>

# app/views/books_coupons/index.html.erb

<h1>Coupons</h1>

<table>
  <thead>
    <tr>
      <th>Code</th>
      <th>Discount</th>
      <th>Expires At</th>
      <th>Max Uses</th>
      <th>Used Count</th>
    </tr>
  </thead>
  <tbody>
    <% @books_coupons.each do |coupon| %>
      <tr>
        <td><%= coupon.code %></td>
        <td><%= number_to_currency(coupon.discount) %></td>
        <td><%= coupon.expires_at %></td>
        <td><%= coupon.max_uses %></td>
        <td><%= coupon.used_count %></td>
      </tr>
    <% end %>
  </tbody>
</table>

預告

明天預計來繼續實作part2吧,我們明天見!


上一篇
Day 19 - CRUD 相關介紹
下一篇
Day 21 - CRUD 實作 part2
系列文
Zero to Ruby on Rails30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言